﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class UIOrder : MonoBehaviour
{
    private const int UI_QUEUE = 3000;

    [SerializeField]
    private int mSortingOrder = 0;

#if UNITY_EDITOR
    //    public bool UpdateOrder = false;
#endif

    Renderer mRenderer = null;
    private int[] PreviousQueues = null;
    private int[] previousSortingOrder = null;
    List<Renderer> childrenderers = null;
    Canvas canvas = null;

    void Awake()
    {
        if (mRenderer == null)
            mRenderer = GetComponent<Renderer>();
    }


    /* private void OnEnable()
     {
         UpdateOrder();
     }
*/
    public int sortingOrder
    {
        get
        {
            if (canvas == null) canvas = GetComponent<Canvas>();
            if (canvas != null) return canvas.sortingOrder;
            return mSortingOrder;
        }
        set
        {
            mSortingOrder = value;
            UpdateOrder();
        }
    }

    private void OnTransformChildrenChanged()
    {
        UpdateOrder();
    }

    private void OnDestroy()
    {
        ResetRenderQueue();
    }

    public void ResetRenderQueue()
    {
        if (childrenderers != null && childrenderers.Count > 0)
        {
            for (int i = 0; i < childrenderers.Count; i++)
            {
                if (childrenderers[i] == null)
                {
                    continue;
                }

                childrenderers[i].sortingOrder = previousSortingOrder[i];
                SetQueue(childrenderers[i], PreviousQueues[i]);
            }
        }
    }


    [ContextMenu("Update Order")]
    public void UpdateOrder()
    {
        if (canvas == null) canvas = GetComponent<Canvas>();

        if (canvas != null)
        {
            canvas.overrideSorting = true;
            canvas.sortingOrder = mSortingOrder;
        }
        else
        {
            if (childrenderers == null)
                childrenderers = new List<Renderer>();
            else
                childrenderers.Clear();
            childrenderers.AddRange(GetComponentsInChildren<Renderer>(true));

            childrenderers.Sort((A, B) =>
            {
                if (A.material == null || B.material == null) return 0;

                if (A.material.renderQueue > B.material.renderQueue)
                    return 1;

                if (A.material.renderQueue < B.material.renderQueue)
                    return -1;

                return 0;
            });

            PreviousQueues = new int[childrenderers.Count];
            previousSortingOrder = new int[childrenderers.Count];


            if (childrenderers != null && childrenderers.Count > 0)
            {
                for (int i = 0; i < childrenderers.Count; i++)
                {
                    if (childrenderers[i] == null)
                    {
                        continue;
                    }

                    PreviousQueues[i] = childrenderers[i].material.renderQueue;
                    previousSortingOrder[i] = childrenderers[i].sortingOrder;
                    SetQueue(childrenderers[i], UI_QUEUE + i);
                    childrenderers[i].sortingOrder = mSortingOrder;
                }
            }
        }
    }

    private void SetQueue(Renderer rend, int queue)
    {
        if (rend != null)
        {
            if (Application.isPlaying)
            {
                if (rend.material != null)
                    rend.material.renderQueue = queue;
            }
            else if (rend.sharedMaterial != null)
                rend.sharedMaterial.renderQueue = queue;
        }
    }

#if UNITY_EDITOR
    void Update()
    {
        canvas = GetComponent<Canvas>();
        if (canvas != null && canvas.sortingOrder != mSortingOrder)
        {
            UpdateOrder();
            //        UpdateOrder = false;
        }
    }
#endif
}
